<template>
  <div class="tools-container">
    <div class="main-card">
      <!-- 页面标题 -->
      <div class="card-header">
        <h2 class="card-title">工具管理</h2>
      </div>
      <div class="search-section">
        <div class="search-container">
          <div class="search-item">
            <span class="search-label">工具名称</span>
            <el-input v-model="queryParams.name" placeholder="请输入工具名称" clearable @keyup.enter="handleQuery"
              class="search-input">
              <template #prefix>
                <el-icon>
                  <Search />
                </el-icon>
              </template>
            </el-input>
          </div>
          <div class="search-item">
            <span class="search-label">分类</span>
            <el-select 
              v-model="queryParams.toolCategoryId" 
              placeholder="请选择分类" 
              clearable 
              style="width: 220px"
              :loading="categoryLoading"
              popper-class="category-select-dropdown"
            >
              <el-option
                v-for="item in categoryOptions"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
          </div>
          <div class="search-buttons">
            <el-button type="primary" @click="handleQuery" :icon="Search">查询</el-button>
            <el-button @click="resetQuery" :icon="RefreshRight">重置</el-button>
          </div>
        </div>
      </div>

      <!-- 工具栏 -->
      <div class="table-toolbar">
        <el-button type="primary" @click="handleAdd" :icon="Plus">新增工具</el-button>
      </div>

      <!-- 表格区域 -->
      <div class="table-section">
        <el-table :data="tableData" fit v-loading="loading" border stripe highlight-current-row
          :cell-style="{ textAlign: 'center' }">
          <el-table-column prop="id" label="ID" align="center" />
          <el-table-column prop="name" label="工具名称" align="center" />
          <el-table-column label="分类" align="center">
            <template #default="{ row }">
              <el-tag
                :type="getRandomTagType(row.toolCategoryId)"
                :effect="getRandomEffect(row.toolCategoryId)"
                class="tag-item"
              >
                {{ getCategoryName(row.toolCategoryId) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="预览图" align="center">
            <template #default="{ row }">
              <el-image 
                :src="row.img" 
                :preview-src-list="[row.img]"
                fit="cover"
                style="width: 40px; height: 40px; border-radius: 4px; cursor: pointer;"
                :preview-teleported="true"
              />
            </template>
          </el-table-column>
          <el-table-column prop="description" label="工具描述" align="center"/>
          <el-table-column prop="fileName" label="文件名" align="center"/>
          <el-table-column prop="downloadCount" label="下载次数" align="center">
            <template #default="{ row }">
              <el-tag type="info">{{ row.downloadCount }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="createTime" label="创建时间" align="center">
            <template #default="{ row }">
              {{ row.createTime}}
            </template>
          </el-table-column>
          <el-table-column prop="updateTime" label="更新时间" align="center">
            <template #default="{ row }">
              {{ row.updateTime }}
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" fixed="right">
            <template #default="{ row }">
              <el-button type="primary" link @click="handleEdit(row)" class="action-button">
                <el-icon>
                  <Edit />
                </el-icon>
                <span>编辑</span>
              </el-button>
              <el-button type="danger" link @click="handleDelete(row)" class="action-button">
                <el-icon>
                  <Delete />
                </el-icon>
                <span>删除</span>
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页区域 -->
        <div class="pagination-container">
          <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
            :page-sizes="[10, 20, 50, 100]" background layout="total, sizes, prev, pager, next, jumper" :total="total"
            @size-change="handleSizeChange" @current-change="handleCurrentChange" />
        </div>
      </div>
    </div>

    <!-- 工具编辑对话框 -->
    <el-dialog 
      v-model="dialogVisible" 
      :title="dialogTitle" 
      width="680px" 
      destroy-on-close
      :close-on-click-modal="false"
      class="tool-dialog"
    >
      <el-form 
        v-if="formData" 
        :model="formData" 
        label-width="90px" 
        :rules="rules" 
        ref="formRef"
        class="tool-form"
      >
        <div class="form-section">
          <div class="form-header">基本信息</div>
          <div class="form-content">
            <el-form-item label="工具名称" prop="name" class="form-item">
              <el-input v-model="formData.name" placeholder="请输入工具名称" />
            </el-form-item>
            <el-form-item label="分类" prop="toolCategoryId" class="form-item">
              <el-select 
                v-model="formData.toolCategoryId" 
                placeholder="请选择分类" 
                class="form-select"
                :loading="categoryLoading"
                clearable
                filterable
                style="width: 100%"
              >
                <el-option
                  v-for="item in categoryOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="工具描述" prop="description" class="form-item full-width">
              <el-input 
                v-model="formData.description" 
                type="textarea" 
                :rows="3" 
                placeholder="请输入工具描述"
                resize="none"
              />
            </el-form-item>
          </div>
        </div>

        <div class="form-section">
          <div class="form-header">文件信息</div>
          <div class="form-content">
            <div class="upload-group">
              <div class="upload-item">
                <span class="upload-label">预览图</span>
                <div class="upload-content">
                  <FileUploader
                    buttonText="上传预览图"
                    accept="image/*"
                    :code="4"
                    ref="imageUploader"
                    @upload-success="handleImageUploadSuccess"
                  />
                  <div v-if="formData.img" class="preview-image">
                    <el-image 
                      :src="formData.img" 
                      fit="cover"
                      :preview-src-list="[formData.img]"
                      :preview-teleported="true"
                    />
                  </div>
                </div>
              </div>

              <div class="upload-item">
                <span class="upload-label">上传文件</span>
                <div class="upload-content">
                  <FileUploader
                    buttonText="选择文件"
                    accept="*/*"
                    :code="4"
                    ref="fileUploader"
                    @upload-success="handleFileUploadSuccess"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm" :loading="submitLoading">提交</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { debounce } from 'lodash-es'
import { Search, RefreshRight, Edit, Delete, Plus, Upload, Document } from '@element-plus/icons-vue'
import { getToolPageList, getToolById, saveTool, deleteToolById } from '@/api/tools'
import { getToolCategoryPageList } from '@/api/toolCategory'
import FileUploader from '@/components/FileUploader.vue'

// 查询参数
const queryParams = reactive({
  name: '',
  toolCategoryId: '',
  pageNum: 1,
  pageSize: 10
})

// 数据列表
const tableData = ref([])
const total = ref(0)
const loading = ref(false)
const categoryOptions = ref([])
const categoryLoading = ref(false)

// 编辑相关
const dialogVisible = ref(false)
const dialogTitle = ref('新增工具')
const formData = ref(null)
const formRef = ref(null)
const submitLoading = ref(false)

// 标签类型和效果
const tagTypes = ['primary', 'success', 'warning', 'danger', 'info']
const tagEffects = ['light', 'dark', 'plain']

// 根据ID获取随机但固定的标签类型
const getRandomTagType = (id) => {
  return tagTypes[id % tagTypes.length]
}

// 根据ID获取随机但固定的标签效果
const getRandomEffect = (id) => {
  return tagEffects[id % tagEffects.length]
}

// 获取分类名称
const getCategoryName = (categoryId) => {
  if (!categoryId) return '未知分类'
  const category = categoryOptions.value.find(item => item.id === categoryId)
  return category ? category.name : '未知分类'
}


// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入工具名称', trigger: 'blur' },
    { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: 'blur' }
  ],
  toolCategoryId: [
    { required: true, message: '请选择分类', trigger: 'change' }
  ],
  description: [
    { required: true, message: '请输入工具描述', trigger: 'blur' },
    { min: 1, max: 200, message: '长度在 1 到 200 个字符', trigger: 'blur' }
  ],
  img: [
    { required: true, message: '请上传预览图', trigger: 'change' }
  ],
  file: [
    { 
      required: true, 
      message: '请上传文件', 
      trigger: 'change',
      validator: (rule, value, callback) => {
        // 如果是编辑模式且有文件名，则不需要验证
        if (formData.value?.id && formData.value?.fileName) {
          callback()
        } else if (!value) {
          callback(new Error('请上传文件'))
        } else {
          callback()
        }
      }
    }
  ]
}

// 获取分类列表
const getCategoryList = async () => {
  if (categoryLoading.value) return
  categoryLoading.value = true
  try {
    const res = await getToolCategoryPageList({ pageSize: 1000 })
    if (res.code === 200) {
      // 确保数据是数组格式
      categoryOptions.value = res.data.records || []
      // 确保数据不为空
      if (categoryOptions.value.length === 0) {
        ElMessage.warning('暂无分类数据')
      }
    } else {
      ElMessage.error({
        message: res.msg || '获取分类列表失败',
        duration: 3000,
        showClose: true
      })
    }
  } catch (error) {
    ElMessage.error({
      message: '获取分类列表出错，请稍后重试',
      duration: 3000,
      showClose: true
    })
  } finally {
    categoryLoading.value = false
  }
}

// 防抖处理查询
const debouncedQuery = debounce(() => {
  getList()
}, 300)

// 获取工具列表
const getList = async () => {
  if (loading.value) return
  loading.value = true
  try {
    const params = {
      name: queryParams.name,
      toolCategoryId: queryParams.toolCategoryId,
      pageNum: queryParams.pageNum,
      pageSize: queryParams.pageSize
    }
    const res = await getToolPageList(params)
    if (res.code === 200) {
      tableData.value = res.data.records
      total.value = res.data.total
    } else {
      ElMessage.error({
        message: res.msg || '获取工具列表失败',
        duration: 3000,
        showClose: true
      })
    }
  } catch (error) {
    console.error('获取工具列表出错:', error)
    if (!error.code || error.code !== 403) {
      ElMessage.error({
        message: '获取工具列表出错，请稍后重试',
        duration: 3000,
        showClose: true
      })
    }
  } finally {
    loading.value = false
  }
}

// 查询按钮
const handleQuery = () => {
  queryParams.pageNum = 1
  debouncedQuery()
}

// 重置按钮
const resetQuery = () => {
  queryParams.name = ''
  queryParams.toolCategoryId = ''
  handleQuery()
}

// 分页大小变化
const handleSizeChange = (size) => {
  queryParams.pageSize = size
  debouncedQuery()
}

// 页码变化
const handleCurrentChange = (current) => {
  queryParams.pageNum = current
  debouncedQuery()
}

// 新增工具
const handleAdd = () => {
  dialogTitle.value = '新增工具'
  formData.value = {
    name: '',
    toolCategoryId: null,
    description: '',
    img: '',
    fileName: '',
    file: null
  }
  dialogVisible.value = true
}

// 编辑工具
const handleEdit = async (row) => {
  dialogTitle.value = '编辑工具'
  const loading = ElLoading.service({
    lock: true,
    text: '正在加载工具信息...',
    background: 'rgba(0, 0, 0, 0.7)'
  })

  try {
    const res = await getToolById(row.id)
    if (res.code === 200) {
      formData.value = {
        id: res.data.id,
        name: res.data.name,
        toolCategoryId: res.data.toolCategoryId,
        description: res.data.description,
        fileName: res.data.fileName,
        img: res.data.img,
        file: null
      }
      dialogVisible.value = true
    } else {
      ElMessage.error({
        message: res.msg || '获取工具详情失败',
        duration: 3000,
        showClose: true
      })
    }
  } catch (error) {
    if (!error.code || error.code !== 403) {
      ElMessage.error({
        message: '获取工具详情出错，请稍后重试',
        duration: 3000,
        showClose: true
      })
    }
  } finally {
    loading.close()
  }
}

// 删除工具
const handleDelete = (row) => {
  ElMessageBox.confirm(
    `确定要删除工具「${row.name}」吗？此操作不可逆。`,
    '删除确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    const loading = ElLoading.service({
      lock: true,
      text: '正在删除...',
      background: 'rgba(0, 0, 0, 0.7)'
    })

    deleteToolById(row.id).then(res => {
      if (res.code === 200) {
        ElMessage.success('删除成功')
        getList() // 刷新列表
      } else {
        ElMessage.error(res.msg || '删除失败')
      }
      loading.close()
    }).catch(error => {
      if (!error.code || error.code !== 403) {
        ElMessage.error('删除失败，请稍后重试')
      }
      loading.close()
    })
  }).catch(() => {
    // 用户取消操作
  })
}

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return

  await formRef.value.validate(async (valid) => {
    if (!valid) return

    submitLoading.value = true
    try {
      const saveData = { 
        ...formData.value,
        // 确保只提交必要的字段
        name: formData.value.name,
        toolCategoryId: formData.value.toolCategoryId,
        description: formData.value.description,
        img: formData.value.img, // 完整的URL
        fileName: formData.value.fileName // 只保存文件名
      }
      const res = await saveTool(saveData)
      if (res.code === 200) {
        ElMessage.success('保存成功')
        dialogVisible.value = false
        getList() // 刷新列表
      } else {
        ElMessage.error(res.msg || '保存失败')
      }
    } catch (error) {
      if (!error.code || error.code !== 403) {
        ElMessage.error('保存失败，请稍后重试')
      }
    } finally {
      submitLoading.value = false
    }
  })
}

// 上传组件引用
const imageUploader = ref(null)
const fileUploader = ref(null)

// 处理图片上传成功
const handleImageUploadSuccess = (result) => {
  formData.value.img = result.fileUrl // 保存完整的URL
}

// 复制文件名
const copyFileName = () => {
  if (formData.value.fileName) {
    navigator.clipboard.writeText(formData.value.fileName)
      .then(() => {
        ElMessage.success('文件名已复制到剪贴板')
      })
      .catch(() => {
        ElMessage.error('复制失败')
      })
  }
}

// 处理文件上传成功
const handleFileUploadSuccess = (result) => {
  formData.value.fileName = result.fileName // 只保存文件名
  formData.value.file = result.file // 保存文件对象用于验证
}

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields()
    formData.value = {
      name: '',
      toolCategoryId: null,
      description: '',
      img: '',
      fileName: '',
      file: null
    }
    
    // 重置上传组件
    if (imageUploader.value) {
      imageUploader.value.resetUploader()
    }
    if (fileUploader.value) {
      fileUploader.value.resetUploader()
    }
  }
}

// 页面加载时获取数据
onMounted(() => {
  getCategoryList()
  getList()
})
</script>

<style scoped>
.tools-container {
  min-height: calc(100vh - 120px);
  background-color: #f5f7fa;
}

.main-card {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.card-header {
  padding: 15px 20px;
  border-bottom: 1px solid #ebeef5;
}

.card-title {
  font-size: 18px;
  font-weight: 500;
  color: #303133;
  margin: 0;
  line-height: 1.5;
}

.search-section {
  padding: 20px;
  border-bottom: 1px solid #ebeef5;
}

.search-container {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  align-items: center;
}

.search-item {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.search-label {
  font-size: 14px;
  color: #606266;
  line-height: 1.5;
}

.search-input {
  width: 220px;
}

.search-buttons {
  display: flex;
  gap: 10px;
  margin-top: 24px;
}

.table-toolbar {
  padding: 0 20px 10px;
  display: flex;
  justify-content: flex-start;
}

.table-section {
  padding: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  width: 100%;
  padding-top: 20px;
  border-top: 1px solid #ebeef5;
}

.action-button {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
}

.action-button .el-icon {
  font-size: 16px;
}

.tag-item {
  padding: 4px 8px;
  margin: 0 2px;
  font-size: 14px;
  min-width: 70px;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
  line-height: 1.5;
}

.form-select {
  width: 100%;
}

/* 响应式设计 */
@media screen and (max-width: 768px) {
  .tools-container {
    padding: 10px;
  }

  .search-container {
    flex-direction: column;
    align-items: flex-start;
  }

  .search-item {
    width: 100%;
  }

  .search-input {
    width: 100%;
  }

  .search-buttons {
    width: 100%;
    margin-top: 15px;
  }
}

:deep(.el-dialog__body) {
  padding: 0 30px;
}

:deep(.el-form-item) {
  margin-bottom: 20px;
}

:deep(.el-input__wrapper) {
  box-shadow: 0 0 0 1px #dcdfe6 inset;
}

:deep(.el-input__wrapper:hover) {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}

:deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px var(--el-color-primary) inset;
}

:deep(.el-select) {
  width: 100%;
}

.preview-image {
  margin-top: 10px;
}

.preview-image :deep(.el-image) {
  width: 100px;
  height: 100px;
  border-radius: 4px;
  cursor: pointer;
}

.file-name {
  margin-top: 10px;
  padding: 12px 16px;
  background-color: #f5f7fa;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: #606266;
  line-height: 1.5;
  word-break: break-all;
  min-height: 44px;

  .el-icon {
    font-size: 18px;
    color: var(--el-color-primary);
    flex-shrink: 0;
  }

  span {
    flex: 1;
    padding-right: 8px;
  }
}

.upload-demo {
  width: 100%;
}

:deep(.el-upload) {
  width: 100%;
}

:deep(.el-upload__tip) {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.tool-form {
  padding: 20px 0;
}

.form-row {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.form-item {
  flex: 1;
  margin-bottom: 0;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  width: 100%;
  padding-top: 20px;
  border-top: 1px solid #ebeef5;
}

/* 响应式设计 */
@media screen and (max-width: 768px) {
  .form-row {
    flex-direction: column;
    gap: 0;
  }
  
  .form-item {
    margin-bottom: 20px;
  }
}

.tool-dialog {
  :deep(.el-dialog__header) {
    margin: 0;
    padding: 20px 30px;
    border-bottom: 1px solid #ebeef5;
  }

  :deep(.el-dialog__body) {
    padding: 0;
  }

  :deep(.el-dialog__footer) {
    padding: 20px 30px;
    border-top: 1px solid #ebeef5;
  }
}

.tool-form {
  padding: 0;
}

.form-section {
  padding: 20px 30px;
  border-bottom: 1px solid #ebeef5;

  &:last-child {
    border-bottom: none;
  }
}

.form-header {
  font-size: 16px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 20px;
  position: relative;
  padding-left: 12px;

  &::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 16px;
    background-color: var(--el-color-primary);
    border-radius: 2px;
  }
}

.form-content {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.form-item {
  margin-bottom: 0;
  flex: 1;
  min-width: 200px;

  &.full-width {
    flex: 0 0 100%;
  }
}

.preview-image {
  margin-top: 10px;

  :deep(.el-image) {
    width: 120px;
    height: 120px;
    border-radius: 6px;
    cursor: pointer;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    transition: all 0.3s;

    &:hover {
      transform: scale(1.02);
    }
  }
}

.file-name {
  margin-top: 10px;
  padding: 12px 16px;
  background-color: #f5f7fa;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: #606266;
  line-height: 1.5;
  word-break: break-all;
  min-height: 44px;

  .el-icon {
    font-size: 18px;
    color: var(--el-color-primary);
    flex-shrink: 0;
  }

  span {
    flex: 1;
    padding-right: 8px;
  }
}

.upload-btn {
  display: flex;
  align-items: center;
  gap: 6px;
}

.upload-demo {
  width: 100%;
}

:deep(.el-upload) {
  width: 100%;
}

:deep(.el-form-item__label) {
  font-weight: 500;
}

:deep(.el-input__wrapper),
:deep(.el-textarea__inner) {
  box-shadow: 0 0 0 1px #dcdfe6 inset;
  transition: all 0.3s;

  &:hover {
    box-shadow: 0 0 0 1px #c0c4cc inset;
  }

  &.is-focus {
    box-shadow: 0 0 0 1px var(--el-color-primary) inset;
  }
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* 响应式设计 */
@media screen and (max-width: 768px) {
  .form-content {
    flex-direction: column;
    gap: 0;
  }

  .form-item {
    margin-bottom: 20px;
  }
}

.category-select-dropdown {
  min-width: 220px !important;
}

:deep(.el-select .el-input__wrapper) {
  box-shadow: 0 0 0 1px #dcdfe6 inset;
}

:deep(.el-select .el-input__wrapper:hover) {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}

:deep(.el-select .el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px var(--el-color-primary) inset;
}

:deep(.el-select .el-input__inner) {
  height: 32px;
  line-height: 32px;
}

:deep(.el-select .el-input__inner::placeholder) {
  color: #909399;
}

.upload-group {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  width: 100%;
}

.upload-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.upload-label {
  width: 80px;
  text-align: right;
  line-height: 32px;
  font-size: 14px;
  color: #606266;
  padding-right: 12px;
  position: relative;
}

.upload-label::before {
  content: '*';
  color: #f56c6c;
  margin-right: 4px;
}

.upload-content {
  flex: 1;
}

.preview-image {
  margin-top: 10px;
}

.preview-image :deep(.el-image) {
  width: 120px;
  height: 120px;
  border-radius: 6px;
  cursor: pointer;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.file-name {
  margin-top: 10px;
  padding: 12px 16px;
  background-color: #f5f7fa;
  border-radius: 6px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: #606266;
  line-height: 1.5;
  word-break: break-all;
  min-height: 44px;
}

.file-name .el-icon {
  font-size: 18px;
  color: var(--el-color-primary);
  flex-shrink: 0;
}

.file-name span {
  flex: 1;
  padding-right: 8px;
}

.upload-btn {
  display: flex;
  align-items: center;
  gap: 6px;
}

@media screen and (max-width: 768px) {
  .upload-group {
    grid-template-columns: 1fr;
    gap: 10px;
  }
}
</style>